import numpy as np
import matplotlib.pyplot as plt

# 中文和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def f(x):
    return x**3 - 3*x**2 + 2

def manual_second_derivative(f, x, h=1e-6):
    """
    使用中心差分法手动计算二阶导数
    公式: f''(x) ≈ [f(x+h) - 2f(x) + f(x-h)] / h²
    """
    return (f(x + h) - 2 * f(x) + f(x - h)) / (h ** 2)

x = np.linspace(-1, 3, 400)
y = f(x)
y_double_prime = [manual_second_derivative(f, xi) for xi in x]

# 创建子图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))

# 绘制函数图像
ax1.plot(x, y, 'b-', linewidth=2, label='y = x^3 - 3x^2 + 2')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.set_title('函数图像')
ax1.grid(True, alpha=0.3)
ax1.legend()

# 绘制二阶导数
ax2.plot(x, y_double_prime, 'r-', linewidth=2, label="y'' = 6x - 6")
ax2.axhline(y=0, color='k', linestyle='-', alpha=0.3)
ax2.axvline(x=1, color='g', linestyle='--', alpha=0.7, label='x=1')
ax2.set_xlabel('x')
ax2.set_ylabel("y''")
ax2.set_title('二阶导数')
ax2.grid(True, alpha=0.3)
ax2.legend()

plt.tight_layout()
plt.show()

# 输出凸性区间
print("凸性分析结果：")
print("当 x < 1 时，函数上凸")
print("当 x > 1 时，函数下凸")